<template>
  <div class="user-list-container">
    <div class="action-bar">
      <!-- 操作区：新增 + 搜索筛选 -->
      <div class="left-tools">
        <a-input
          v-model="searchText"
          placeholder="按姓名或邮箱搜索"
          style="width: 220px; margin-right: 8px;"
        />
        <a-select
          v-model="statusFilter"
          placeholder="选择状态"
          style="width: 160px; margin-right: 8px;"
          :allowClear="true"
        >
          <a-select-option value="">全部状态</a-select-option>
          <a-select-option value="active">活跃</a-select-option>
          <a-select-option value="inactive">禁用</a-select-option>
        </a-select>
        <a-button type="primary" @click="handleSearch" style="margin-right: 8px;">查询</a-button>
        <a-button @click="resetFilters" style="margin-right: 8px;">重置</a-button>
      </div>
      <div class="right-tools">
        <a-button type="primary" @click="showAddModal = true">
          添加用户
        </a-button>
      </div>
    </div>

    <!-- 用户列表表格 -->
    <a-table
      :columns="computedColumns"
      :dataSource="users"
      :loading="loading"
      rowKey="id"
      :pagination="tablePagination"
      @change="handleTableChange"
    >
      <!-- 操作列的自定义渲染：在列配置里声明 customRender: 'action'，这里对应 slot="action" -->
      <span slot="action" slot-scope="text, record">
        <a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
        <a-popconfirm title="确定要删除这个用户吗？" okText="确定" cancelText="取消" @confirm="handleDelete(record.id)">
          <a-button type="link" danger size="small">删除</a-button>
        </a-popconfirm>
      </span>
    </a-table>

    <!-- 添加用户模态框 -->
    <a-modal v-model="showAddModal" title="添加新用户" @ok="handleAdd" @cancel="resetForm">
      <a-form :model="formData" layout="vertical">
        <a-form-item label="姓名" required>
          <a-input v-model="formData.name" placeholder="请输入姓名" />
        </a-form-item>
        <a-form-item label="邮箱" required>
          <a-input v-model="formData.email" placeholder="请输入邮箱" />
        </a-form-item>
        <a-form-item label="年龄">
          <a-input-number v-model="formData.age" :min="1" :max="120" style="width: 100%" />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 编辑用户模态框 -->
    <a-modal v-model="showEditModal" title="编辑用户" okText="保存" cancelText="取消" @ok="handleEditSubmit" @cancel="handleEditCancel">
      <a-form :model="formData" layout="vertical">
        <a-form-item label="姓名" required>
          <a-input v-model="formData.name" placeholder="请输入姓名" />
        </a-form-item>
        <a-form-item label="邮箱" required>
          <a-input v-model="formData.email" placeholder="请输入邮箱" />
        </a-form-item>
        <a-form-item label="年龄">
          <a-input-number v-model="formData.age" :min="1" :max="120" style="width: 100%" />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script>
// 小白注解：这是 Vue2 的选项式写法（Options API），所有的状态都在 data 里，逻辑在 methods 里
// 我们通过 fetch 调用后端的 API：http://localhost:3000/api/users，实现增删改查
import { message } from 'ant-design-vue'

export default {
  name: 'UserList',

  data() {
    return {
      // 表格列配置（告诉 a-table 每列显示什么）
      columns: [
        { title: 'ID', dataIndex: 'id', key: 'id', width: 80 },
        { title: '姓名', dataIndex: 'name', key: 'name', width: 120 },
        { title: '邮箱', dataIndex: 'email', key: 'email' },
        { title: '年龄', dataIndex: 'age', key: 'age', width: 80 },
        { title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', width: 180 },
        { title: '操作', key: 'action', width: 160, scopedSlots: { customRender: 'action' } },
      ],

      users: [],        // 用户列表数据
      loading: false,   // 加载状态
      showAddModal: false, // 添加模态框开关
      showEditModal: false, // 编辑模态框开关
      editingUser: null,    // 当前正在编辑的用户
      formData: {           // 表单数据（添加/编辑共用）
        name: '',
        email: '',
        age: 18
      },

      // 搜索与筛选
      searchText: '',       // 搜索关键字（匹配姓名和邮箱）
      statusFilter: '',     // 状态筛选：active/inactive/''(全部)

      // 分页与排序（改为服务端处理）
      pagination: {
        current: 1,
        pageSize: 10,
        showSizeChanger: true,
        pageSizeOptions: ['5', '10', '20', '50']
      },
      paginationTotal: 0, // 服务端返回的总条数
      sorter: { field: 'id', order: 'descend' } // 默认按ID倒序，服务端排序
    }
  },

  /**
   * 函数：fetchUsers（获取用户列表）
   * 用途：页面加载或操作后刷新用户数据
   * 前因：前端需要展示最新的用户列表
   * 后果：把后端返回的用户数据设置到 users，让表格展示
   * 逻辑步骤：
   * 1）设置 loading 为 true；
   * 2）请求后端 GET /api/users；
   * 3）解析返回，成功则赋值 users，失败则提示；
   * 4）最后把 loading 设回 false。
   */
  methods: {
    /**
     * 函数：handleSearch（执行查询）
     * 用途：点击查询按钮时，把分页重置到第1页，让筛选结果从第一页显示
     * 小白解释：搜索不会请求后端，我们在前端内存里筛选和排序，简单快速
     */
    handleSearch() {
      this.pagination.current = 1
      this.fetchUsers()
    },

    /**
     * 函数：resetFilters（重置筛选与排序）
     * 用途：清空搜索关键字与状态筛选，同时还原分页/排序
     * 逻辑步骤：清空两个筛选 → 重置分页到第1页 → 清除排序
     */
    resetFilters() {
      this.searchText = ''
      this.statusFilter = ''
      this.pagination = { ...this.pagination, current: 1 }
      this.sorter = { field: 'id', order: 'descend' }
      this.fetchUsers()
    },

    /**
     * 函数：fetchUsers（服务端获取用户列表）
     * 用途：带上分页、搜索、状态筛选、排序参数请求后端
     * 小白解释：把页面里的筛选条件拼到 URL 上，后端返回对应一页数据和总条数，省内存更稳定
     */
    async fetchUsers() {
      this.loading = true
      try {
        const params = new URLSearchParams({
          page: this.pagination.current,
          limit: this.pagination.pageSize,
          search: this.searchText || '',
          status: this.statusFilter || '',
          sortField: this.sorter.field || 'id',
          sortOrder: this.sorter.order || 'descend'
        })
        const res = await fetch(`http://localhost:3000/api/users?${params.toString()}`)
        if (!res.ok) throw new Error('网络响应失败')
        const result = await res.json()
        if (result.success) {
          this.users = result.data.users
          // 同步服务端分页信息
          const p = result.data.pagination || {}
          this.paginationTotal = Number(p.total || 0)
          this.pagination = {
            ...this.pagination,
            current: Number(p.current || this.pagination.current),
            pageSize: Number(p.pageSize || this.pagination.pageSize)
          }
          this.sorter = {
            field: p.sortField || this.sorter.field,
            order: (p.sortOrder || this.sorter.order).toLowerCase() === 'asc' ? 'ascend' : this.sorter.order
          }
        } else {
          message.error(result.message || '获取用户列表失败')
        }
      } catch (e) {
        console.error('获取用户列表失败：', e)
        message.error('获取用户列表失败，请检查后端服务是否运行')
      } finally {
        this.loading = false
      }
    },

    /**
     * 函数：handleAdd（添加用户）
     * 用途：提交添加表单，把新用户保存到后端
     * 前因：用户在弹框里填写了姓名、邮箱、年龄
     * 后果：成功后刷新列表，并关闭弹框、重置表单
     * 逻辑步骤：
     * 1）表单校验；
     * 2）POST /api/users 提交数据；
     * 3）成功后把新用户插入 users 顶部；
     * 4）关闭弹框并重置表单；
     * 5）提示成功。
     */
    async handleAdd() {
      if (!this.formData.name || !this.formData.email) {
        message.warning('请填写完整信息')
        return
      }

      try {
        const res = await fetch('http://localhost:3000/api/users', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.formData)
        })
        const result = await res.json()
        if (result.success) {
          this.users.unshift(result.data)
          this.showAddModal = false
          this.resetForm()
          message.success('添加用户成功！')
        } else {
          message.error(result.message || '添加用户失败')
        }
      } catch (e) {
        console.error('添加用户失败：', e)
        message.error('添加用户失败，请检查后端服务')
      }
    },

    /**
     * 函数：handleEdit（打开编辑弹框）
     * 用途：把当前行的用户信息放到表单，显示编辑弹框
     * 前因：用户点击了某一行的“编辑”按钮
     * 后果：打开弹框并填充数据，等待保存
     * 逻辑步骤：1）记录当前用户；2）把其数据复制到 formData；3）打开弹框。
     */
    handleEdit(user) {
      this.editingUser = user
      this.formData = {
        name: user.name,
        email: user.email,
        age: user.age
      }
      this.showEditModal = true
    },

    /**
     * 函数：handleEditSubmit（提交编辑）
     * 用途：把编辑后的数据提交到后端，更新该用户
     * 前因：用户在编辑弹框里点击了“保存”
     * 后果：后端更新成功后，同步到前端列表并关闭弹框
     * 逻辑步骤：
     * 1）确认有 editingUser；
     * 2）PUT /api/users/:id 提交修改；
     * 3）更新本地 users 对应项；
     * 4）关闭弹框、重置表单、清空 editingUser；
     * 5）提示成功。
     */
    async handleEditSubmit() {
      try {
        if (!this.editingUser) return
        const res = await fetch(`http://localhost:3000/api/users/${this.editingUser.id}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.formData)
        })
        const result = await res.json()
        if (result.success) {
          const idx = this.users.findIndex(u => u.id === this.editingUser.id)
          if (idx !== -1) {
            this.$set(this.users, idx, { ...this.users[idx], ...this.formData })
          }
          this.showEditModal = false
          this.resetForm()
          this.editingUser = null
          message.success('用户更新成功！')
        } else {
          message.error(result.message || '更新用户失败')
        }
      } catch (e) {
        console.error('更新用户失败：', e)
        message.error('更新用户失败，请检查后端服务')
      }
    },

    /**
     * 函数：handleDelete（删除用户）
     * 用途：调用后端删除接口并在前端移除该用户
     * 前因：用户点击了“删除”并确认
     * 后果：列表中该用户消失
     * 逻辑步骤：1）调用 DELETE /api/users/:id；2）成功后过滤 users；3）提示成功。
     */
    async handleDelete(id) {
      try {
        const res = await fetch(`http://localhost:3000/api/users/${id}`, { method: 'DELETE' })
        const result = await res.json()
        if (result.success) {
          this.users = this.users.filter(u => u.id !== id)
          message.success('删除用户成功！')
        } else {
          message.error(result.message || '删除用户失败')
        }
      } catch (e) {
        console.error('删除用户失败：', e)
        message.error('删除用户失败，请检查后端服务')
      }
    },

    /**
     * 函数：resetForm（重置表单）
     * 用途：清空表单，让下一次添加或编辑从干净状态开始
     * 前因：用户取消或提交后需要回到初始状态
     * 后果：三个字段清空/恢复默认值
     */
    resetForm() {
      this.formData = { name: '', email: '', age: 18 }
    },

    /**
     * 函数：handleEditCancel（关闭编辑弹框）
     * 用途：当用户点击“取消”时，关闭弹框并清理状态
     */
    handleEditCancel() {
      this.showEditModal = false
      this.resetForm()
      this.editingUser = null
    },

    /**
     * 函数：handleTableChange（表格分页/排序回调）
     * 用途：当用户点击表头排序或翻页时，更新本地的分页和排序状态
     * 参数：
     *  - pagination：包含 current（当前页）、pageSize（每页条数）
     *  - filters：表格筛选（本例未使用）
     *  - sorter：包含 field（排序字段）、order（'ascend'/'descend'/null）
     */
    handleTableChange(pagination, filters, sorter) {
      this.pagination = { ...this.pagination, current: pagination.current, pageSize: pagination.pageSize }
      // 兼容不同版本的 sorter 字段
      const field = sorter.field || sorter.columnKey || (sorter.column && sorter.column.dataIndex) || this.sorter.field
      this.sorter = { field, order: sorter.order || this.sorter.order }
      // 变更分页或排序后，重新请求服务端数据
      this.fetchUsers()
    },

    /**
     * 函数：compareValues（通用比较函数）
     * 用途：根据字段值进行升序或降序比较，支持数字和字符串
     * 小白解释：排序就是比较两条数据谁应该在前谁在后
     */
    compareValues(a, b, field) {
      const va = a[field]
      const vb = b[field]
      if (va == null && vb == null) return 0
      if (va == null) return -1
      if (vb == null) return 1
      // 数字比较或字符串比较
      if (typeof va === 'number' && typeof vb === 'number') {
        return va - vb
      }
      return String(va).localeCompare(String(vb))
    }
  },

  computed: {
    /**
     * 计算属性：computedColumns（带排序标记的列）
     * 用途：在列上声明哪些字段支持排序，并通过 sortOrder 控制当前排序箭头显示
     */
    computedColumns() {
      const sortableFields = new Set(['id', 'name', 'email', 'age', 'createdAt'])
      return this.columns.map(col => {
        if (sortableFields.has(col.dataIndex)) {
          const sortOrder = this.sorter.field === col.dataIndex ? this.sorter.order : null
          return { ...col, sorter: true, sortOrder }
        }
        return col
      })
    },

    /**
     * 计算属性：filteredAndSortedUsers（前端本地筛选 + 排序）
     * 用途：根据搜索关键字和状态筛选，再按当前排序字段进行排序
     */
    // 移除前端本地筛选与排序，统一改为服务端

    /**
     * 计算属性：tablePagination（表格分页配置）
     * 用途：把总条数设置为筛选后的数量，确保页码显示正确
     */
    tablePagination() {
      return { ...this.pagination, total: this.paginationTotal }
    }
  },

  /**
   * 生命周期：created
   * 用途：组件创建完成后自动调用，适合初始化数据
   * 这里我们在页面加载时拉取用户列表
   */
  created() {
    this.fetchUsers()
  }
}
</script>

<style scoped>
.action-bar { margin-bottom: 16px; display: flex; justify-content: flex-end; }
.user-list-container { padding: 8px; }
</style>